public class ULA {
	private short valor;
	private UC uc;
	private MUXA muxa;
	private MUXB muxb;
	
	public boolean carry;
	public boolean overflow;
	public boolean paridade;
	public boolean zero;
	public boolean sinal;
	
	

	public ULA(UC uc, MUXA muxa, MUXB muxb)
	{
		this.uc = uc;
		this.muxa = muxa;
		this.muxb = muxb;
	}
	
	public void atualizarValor()
	{
		String control = uc.getSinais("ULA");
		int temp = 0;
		short a = muxa.getValor();
		short b = muxb.getValor();
		if(control.equals("000000")) temp = (a + b);	 
		if(control.equals("000001")) temp = (a - b);
		if(control.equals("000010")) temp = (b - a);
		if(control.equals("000011")){temp = a; b=0;} 
		if(control.equals("000100")){temp =  b; a=0;}
		if(control.equals("000101")) temp = (a & b);
		if(control.equals("000110")) temp = (a | b);
		if(control.equals("000111")) temp = (a ^ b);
		if(control.equals("001000")){temp = ~a; b=0;}
		if(control.equals("001001")){temp = ~b; a=0;}
		if(control.equals("001010")) temp =  0;
		if(control.equals("001011")){temp = -a; b=0;}
		if(control.equals("001100")){temp = -b; a=0;}
		if(control.equals("001101")){temp = shl(a);b=0;}
		if(control.equals("001110")){temp = shr(a);b=0;}
		if(control.equals("010010")){temp = (b + 1);a=0;}
		
		atualizaFlags(temp);
		
		valor = (short)temp;
	}
	
	 private void status(short v)
	 {
        System.out.println("R: "+ toHexString(v) + " , " + toBinaryString(v));
        System.out.println("carry: "+ carry);
        System.out.println("overflow: "+ overflow);
        System.out.println("paridade: "+ paridade);
        System.out.println("zero: "+ zero);
        System.out.println("sinal: "+ sinal + "\n"); 
	 }
	
    private void atualizaFlags(int vint) {
        short v = (short)vint;
        carry = testaCarry(vint);
		overflow = testaOverflow(vint);
		paridade = testaParidade(v);
		zero = testaZero(v);
		sinal = testaSinal(v);
		
		//status(v);
    }

    private short shl(int n) {
		
		return (short)(n*2);
	}
	
	private short shr(int n) {
		
		return (short)(n/2);
	}
	
	private String toHexString(int n)
	{
		String entrada = Integer.toHexString(n);
		String zeros = "";
		for (int i = 0; i < 4 - entrada.length(); i++) {
			zeros += "0";
		}	
		
		String saida = zeros + entrada; 
		return saida;
	}

	
	private String toBinaryString(int n)
	{
		String entrada = Integer.toBinaryString(n);
		String zeros = "";
		for (int i = 0; i < 16 - entrada.length(); i++) {
			zeros += "0";
		}	
		
		String saida = zeros + entrada; 
		return saida;
	}
	
	private boolean testaCarry(int v)
	{
	    if (nBits(v) > 16) {
            return true;
        }
	    else return false;	    
	}
	
	private boolean testaOverflow(int v)
	{
	    if ((v > Short.MAX_VALUE) || (v < Short.MIN_VALUE)) {
            return true;
        } else {
            return false;
        }
	   	        

	}
	
	private boolean testaSinal(short v)
	{	    
	    if (v < 0) return true;
	    else return false;
	}
	
	private boolean testaParidade(short v)
	{
	    boolean p = true;
	    String vs = toBinaryString(v);
	    for (int i = 0; i < vs.length(); i++) {
            if (vs.charAt(i) == '1')
            {
               p = !p; 
            }
        }
	    return p;
	}
	
	private int nBits(int v)
	{	    
	    String vs = toBinaryString(v);
	    return vs.length(); 
	}
	private boolean testaZero(short v)
	{
	    if (v == 0) { return true; } 
	    else { return false; }	   
	}
	
	public void setValor(short valor) { this.valor = valor; }
	public short getValor() { return (short)valor; }
}
 
 